package codegen

import (
	"fmt"
	"gitee.com/hxchjm/goge/codegen/utils"
	"gitee.com/hxchjm/goge/codegen/utils/pathx"
	"github.com/siddontang/go/config"
	"strings"
)

const appTemplate = `package app

import (
	"context"
	"time"

	"{{.serviceName}}/internal/dao"
	"{{.serviceName}}/internal/server/grpc"
	"{{.serviceName}}/internal/server/http"
	"{{.serviceName}}/internal/service"

	"go-main/library/log"
	"go-main/library/net/http/dam"
	"go-main/library/net/rpc/warden"
)

type App struct {
	svc  *service.Service
	http *dam.Engine
	grpc *warden.Server
}


func Init() (*App, func(), error) {
	redis, cleanup, err := dao.NewRedis()
	if err != nil {
		return nil, nil, err
	}

	db, cleanup2, err := dao.NewDB()
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	daoDao, cleanup3, err := dao.New(redis, db)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	serviceService, cleanup4, err := service.New(daoDao)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	engine, err := http.New(serviceService)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	server, err := grpc.New(serviceService)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	app, cleanup5, err := NewApp(serviceService, engine, server)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	return app, func() {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}


func NewApp(svc *service.Service, h *dam.Engine, g *warden.Server) (app *App, closeFunc func(), err error) {
	app = &App{
		svc:  svc,
		http: h,
		grpc: g,
	}
	closeFunc = func() {
		ctx, cancel := context.WithTimeout(context.Background(), 35*time.Second)
		if err = g.Shutdown(ctx); err != nil {
			log.Error("grpcSrv.Shutdown error(%v)", err)
		}
		if err = h.Shutdown(ctx); err != nil {
			log.Error("httpSrv.Shutdown error(%v)", err)
		}
		cancel()
	}
	return
}
`

func genApp(dir, rootPkg string, cfg *config.Config, filename string) error {
	//name := strings.ToLower(api.Service.Name)
	//filename, err := format.FileNamingFormat(cfg.NamingFormat, name)
	//if err != nil {
	//	return err
	//}

	/*	filename := name
		configName := filename
		if strings.HasSuffix(filename, "-api") {
			filename = strings.ReplaceAll(filename, "-api", "")
		}*/

	return utils.GenFile(utils.FileGenConfig{
		Dir:          dir,
		Subdir:       appDir,
		Filename:     filename,
		TemplateName: "mainTemplate",
		//Category:        category,
		//TemplateFile:    mainTemplateFile,
		BuiltinTemplate: appTemplate,
		Data: map[string]string{
			"importPackages": genAppImports(rootPkg),
			"serviceName":    rootPkg,
		},
	})
}

func genAppImports(parentPkg string) string {
	var imports []string
	imports = append(imports, fmt.Sprintf("\"%s\"", pathx.JoinPackages(parentPkg, appDir)))
	//imports = append(imports, fmt.Sprintf("\"%s/core/conf\"", vars.ProjectOpenSourceURL))
	//imports = append(imports, fmt.Sprintf("\"%s/rest\"", vars.ProjectOpenSourceURL))
	return strings.Join(imports, "\n\t")
}
